<?php
    class WZ_Crud
    {
        static $_instance = array();
        static $_db;
        static $_model;
        static $_service;
        static $_form;
        static $_table;
        static $_request;
        static $_primary;
        static $_fields;
        static $_captcha;
        static $_captchaHash;
        static $_token;
        static $_status = 'NOK';
        
        public static function factory($model)
        {
            $class = get_class($model);
            static::$_table = $table = strtolower(end(explode('_', $class)));
            static::$_service = $serviceClass = str_replace('WZModel_', 'WZService_', $class);
            $serviceClass::init();
            $formClass = str_replace('WZModel_', 'WZForm_', $class);
            static::$_db = $serviceClass::getDb();
            static::$_request = \WZ_Request::getInstance();
            $session = \WZ_Session::getInstance('WZCaptchaCrud');
            $varCodeGetter = 'getCaptchacode';
            $varHashGetter = 'getCaptchahash';
            static::$_captcha = $session->$varCodeGetter();
            static::$_captchaHash = $session->$varHashGetter();
            $session = $session->delete();
            static::$_model = $model;
            static::$_form = new $formClass;
            $expiration = time + 900; //15 minutes
            static::$_token = sha1($expiration . session_id() . static::$_form->getName());
            static::fields();
            if (!array_key_exists($table, static::$_instance)){
                static::$_instance[$table]  = new self;
            }
            return static::$_instance[$table];
        }
        
        public static function fields()
        {
            $infos = static::$_db->info();
            static::$_primary = $infos['primary'];
            static::$_fields = $infos['metadata'];
        }
        
        public static function isNullable($field)
        {
            foreach (static::$_fields as $fieldName => $schema) {
                if ($fieldName == $field) {
                    return $schema['NULLABLE'];
                }
            }
            return false;
        }
        
        public static function read($id)
        {
            $service = static::$_service;
            return $service::find($id);
        }
        
        public static function create()
        {
            $request = static::$_request;
            $form = static::$_form;
            \WZ_Form::submit($form, 'submit', 'Ajouter');
            \WZ_Form::getToken(static::$_form);
            
            if ($request->isPost() && $form->isValid($_POST)) {
                $create = true;
                $token = $request->getParam('token');
                if (null !== static::$_captchaHash) {
                    $verif = $request->getParam('captcha');
                    if ($verif != static::$_captcha) {
                        $error = __('Vérification incorrecte', false);
                        $form->getElement('captcha')->addError($error);
                        $create = false;
                    }
                }
                if ($token != static::$_token) {
                    $error = __('Token invalide', false);
                    $form->getElement('submit')->addError($error);
                    $create = false;
                }
                if (true === $create) {
                    $params = $request->getParams();
                    unset($params['token']);
                    unset($params['submit']);
                    if (isset($params['captcha'])) {
                        unset($params['captcha']);
                    }
                    $obj = new static::$_model;
                    foreach ($params as $key => $value) {
                        $setter = 'set' . ucfirst(\WZ_Inflector::camelize($key));
                        $obj->$setter($value);
                    }
                    $newObj = $obj->save();
                    static::$_status = 'OK';
                }
            }
            $render = \WZ_Form::render($form);
            return $render;
        }
    }